Reference vs. Reference

I feel there is a subtle point that needs clarification.
Unfortunately the term “reference” does not have an unambiguous
meaning in our field. I know at least these meanings

  1. R. is a general term for any programming language construct that
    allows to reference a value. This does not sound very involved but
    it’s actually as simple (or: as general) as that. :slight_smile: Unfortunately
    this includes things like C pointers, Pascal pointers, C++ references,
    Perl references, Ruby references (Matz, is this the proper term?) etc.

  2. C++ R. type is a special beast which has some additional properties
    compared to 1. This does not only allow to reference a value but in
    fact you can say that it references a reference[1]. Or you can say
    that a C++ reference is an alias for a variable. Hence it allows to
    manipulate a variable in a calling scope.

See also http://en.wikipedia.org/wiki/Reference#Computer_science

Ruby’s evaluation strategy is actually “call by reference” although
the description at
http://en.wikipedia.org/wiki/Call_by_reference#Call_by_reference does
not cover Ruby properly - unless you interpret “temporary object” as
“copy of a reference” because this is how it works.

Note: I do not cover special cases like Fixnums here because from the
Ruby programmer’s perspective there is no difference in behavior -
just in speed and memory.

Kind regards

robert

On 10/1/07, Robert K. [email protected] wrote:

  1. C++ R. type is a special beast which has some additional properties
    compared to 1. This does not only allow to reference a value but in
    fact you can say that it references a reference[1]. Or you can say
    that a C++ reference is an alias for a variable. Hence it allows to
    manipulate a variable in a calling scope.

See also http://en.wikipedia.org/wiki/Reference#Computer_science

Ruby’s evaluation strategy is actually “call by reference”
Sorry Robert but I challange that statement, “call by value” by all
means
I also think that I am not the only one to do so.
If it were call by reference we could change parameters of immediate
values, which we can not:
a = 42
def change b
b = 22
end
change a
p a # --> 42
although
the description at
http://en.wikipedia.org/wiki/Call_by_reference#Call_by_reference does
not cover Ruby properly - unless you interpret “temporary object” as
“copy of a reference” because this is how it works.
Maybe call by copy is the exact term; what you think?

Note: I do not cover special cases like Fixnums here because from the
Ruby programmer’s perspective there is no difference in behavior -
just in speed and memory.
Why would Fixnums (e.g. intermediate values) be a special case for
call semantics?

Kind regards

robert

Likewise squared :wink:

On 10/1/07, Robert K. [email protected] wrote:

reference" because that’s basically what happens. But I haven’t seen
this term either; I don’t think it is standard. So I’d say it’s “call
by reference” because that describes best what happens, especially that
callers see manipulations of objects. And the fact that Ruby does not
have the aliasing effects that C++ references exhibit does not
disqualify the term “call by reference” for Ruby.

Behavior wise it’s the same as passing a pointer to a C function. You
can change the pointer in the function without affecting the pointer in
the caller. Yet both refer on function invocation to the same value.

I agree with Robert D… What ruby does is not call-by-reference.
Every other place I’ve seen this phrase used it means that when you
pass an lvalue to the function and the function modifies the
corresponding argument, it modifies that lvalue. The “reference” in
call-by-reference is a reference to an lvalue, not an object. C++
isn’t the only language that has this concept.

In C, you can emulate this concept easily by passing the address of an
lvalue and the function dereferencing that pointer to modify the
lvalue. There is no easy built-in way to do this in Ruby. The
solution is typically to return the new value and have the caller
explicitly assign the lvalue.

I’m not saying that the functionality that Ruby has is a major issue
(although there have been occasions where I’ve wanted a pointer
concept), but saying that it does call-by-reference is just not true.

The calling mechanism in Ruby seems closest to passing pointers to
values in C, where all variables also contain pointers to values. I
think of all ruby variables as object pointers and it makes sense to
me. If I needed to put a name to calling mechanism (which I don’t), I
guess I’d say call-by-pointer. The pointer doesn’t necessarily have
to be a memory address though. Or you might say that ruby’s variables
are all object pointers and ruby does call by value.

Eric

I’m catching up after being away for a few days, and this seems to
have been a hot topic lately.

I’ve seen the term call by object reference used many times in the
past to distinguish what happens in languages like Ruby and Smalltalk
from the usual meaning of call by reference.

The difference is that call by reference implies giving the called
routine read/write access to the variable which holds a reference to
some data. And call by object reference gives the called method read
access to a reference to an object. The called routine can NOT change
the reference, it can only invoke methods on the referenced object.

Note that although Ruby does allow assignment to a parameter
‘variable’ this is only moving a ‘sticky note’ to use Austin Z’s nice
analogy.


Rick DeNatale

My blog on Ruby
http://talklikeaduck.denhaven2.com/

On 10/2/07, Rick DeNatale [email protected] wrote:

access to a reference to an object. The called routine can NOT change
the reference, it can only invoke methods on the referenced object.

Note that although Ruby does allow assignment to a parameter
‘variable’ this is only moving a ‘sticky note’ to use Austin Z’s nice
analogy.

That’s pretty much how I feel things are, if “call by object
reference” is used in the Smalltalk community I see no obvious reason
why not to steal it ;). Ruby and Smalltalk do share the parameter
passing semantics after all.

A side remark to Robert’s witty remark about the “truth value and
number of supporters”. This was really funny and a good defense, but
on the serious side, I honor the opinions of most of the lists
‘regulars’, even if I do not show it well all the time - which is bad
style from my part :(. (Comment ça va Xavier? :wink:

Cheers
Robert

On 01.10.2007 22:07, Robert D. wrote:

  1. C++ R. type is a special beast which has some additional properties
    compared to 1. This does not only allow to reference a value but in
    fact you can say that it references a reference[1]. Or you can say
    that a C++ reference is an alias for a variable. Hence it allows to
    manipulate a variable in a calling scope.

See also http://en.wikipedia.org/wiki/Reference#Computer_science

Ruby’s evaluation strategy is actually “call by reference”
Sorry Robert but I challange that statement,

It’s a free country… :slight_smile:

“call by value” by all means
I also think that I am not the only one to do so.

You are not insinuating that the truth value of your statement somehow
depends on the higher number of supporters, do you? :slight_smile:

If it were call by reference we could change parameters of immediate
values, which we can not:
a = 42
def change b
b = 22
end
change a
p a # --> 42

Well, I believe the error is in reading “reference” in “call by
reference” as “C++ reference” (see the initial section of my posting).
In C++ land “reference” has a special meaning that is not identical with
the general term “reference”, which is used in the equally general term
“call by reference”.

Counter challenge: If Ruby was using “call by value” this bit would
print “” and not “X”, because t() would see a /copy of the string/:

$ ruby -e ‘def t(x)x<<“X"end;s=”";t s;p s’
“X”

although
the description at
http://en.wikipedia.org/wiki/Call_by_reference#Call_by_reference does
not cover Ruby properly - unless you interpret “temporary object” as
“copy of a reference” because this is how it works.
Maybe call by copy is the exact term; what you think?

I have never heard this term before; I would guess it’s not a standard
CS term. One could argue that Ruby uses something like “call by copy of
reference” because that’s basically what happens. But I haven’t seen
this term either; I don’t think it is standard. So I’d say it’s “call
by reference” because that describes best what happens, especially that
callers see manipulations of objects. And the fact that Ruby does not
have the aliasing effects that C++ references exhibit does not
disqualify the term “call by reference” for Ruby.

Behavior wise it’s the same as passing a pointer to a C function. You
can change the pointer in the function without affecting the pointer in
the caller. Yet both refer on function invocation to the same value.

Note: I do not cover special cases like Fixnums here because from the
Ruby programmer’s perspective there is no difference in behavior -
just in speed and memory.
Why would Fixnums (e.g. intermediate values) be a special case for
call semantics?

Because technically (i.e. under the hoods) the reference is the value.
But from a language behavior point of view (i.e. ignoring the
implementation) there is no observable difference. I always find it
easier to grasp when this special case is not pointed out initially.
It’s a mere implementation detail of Ruby but does not affect how the
language works.

Kind regards

robert

Likewise squared :wink:

Raised to the power of three. :slight_smile:

robert

Hi,

In PHP 4 and 5 you have references which work similar like C++
references. E.g. you can make a variable reference another variable
after which if you change the value of one of those variables the other
variable’s value will also be “updated”. An example:

$x = 1;
$y = &$x; // y references x
$x = 2;
echo $y; // 2
$y = 3;
echo $x; // 3

In PHP 4 you always had to pass objects by reference if you didn’t want
to end up with a copy of your object.

$x = new Object();
$x->value = 1;
$y = $x; // copy
echo $y->value; // 1
$y->value = 2;
echo $x->value; // 1
$x->value = 3;
echo $y->value; // 2
$y = &$x; // reference
echo $y->value; // 3
$y->value = 4;
echo $x->value; // 4;
$x->value = 5;
echo $y->value; // 5

However, in PHP 5 they introduced a concept similar to the “references”
we know in Ruby. But because they already used the term “reference” they
had to come up with a different name, so they call them object handles.
If you assign an object to a variable you are assigning an object handle
to the variable. If you assign the value of the first variable to
another variable you are assigning it the same object handle. So both
variables “reference” the same object. But if you now assign another
object to the first (or second) variable, only that variable’s content
changes. E.g.

$x = new stdClass();
$y = $x; // assign object handle
$x->value = 2;
echo $y->value; // 2
$y->value = 3;
echo $x->value; // 3
$x = new stdClass(); // assign different object handle
$x->value = 1;
echo $y->value; // 3

So maybe we should call them handles instead of references to clarify
the difference?

Regards,

Peter

Rick DeNatale wrote:

Two uses of object handles were in the earliest implementations of
Smalltalk, and in the old Macintosh OS.

I remember those. You had to lock them while accessing the data, because
the memory manager might try to shunt them around, IIRC.

On 10/2/07, Peter C. Verhage [email protected] wrote:

Hi,

In PHP 4 and 5 you have references which work similar like C++
references. E.g. you can make a variable reference another variable
after which if you change the value of one of those variables the other
variable’s value will also be “updated”.

However, in PHP 5 they introduced a concept similar to the “references”
we know in Ruby. But because they already used the term “reference” they
had to come up with a different name, so they call them object handles.

So maybe we should call them handles instead of references to clarify
the difference?

I don’t know how it relates to PHP 5, but historically object handles
meant something different.

One way to implement an object memory/heap is to use a level of
indirection, an object is represented by what’s effectively an element
in an array of pointers, with the pointer holding the address of an
object’s state. Variables refer not to the object directly but to the
pointer, which is called a handle. This allows the objects to be
moved (during GC for example) without requiring all references to the
object to be relocated.

Two uses of object handles were in the earliest implementations of
Smalltalk, and in the old Macintosh OS.

I prefer the term Object Reference myself, and see Object Handle as a
particular implementation (at least as the term applies to the systems
I just described).


Rick DeNatale

My blog on Ruby
http://talklikeaduck.denhaven2.com/

On Oct 3, 2007, at 5:23 AM, Rick DeNatale wrote:

One way to implement an object memory/heap is to use a level of
indirection, an object is represented by what’s effectively an element
in an array of pointers, with the pointer holding the address of an
object’s state. Variables refer not to the object directly but to the
pointer, which is called a handle. This allows the objects to be
moved (during GC for example) without requiring all references to the
object to be relocated.

Two uses of object handles were in the earliest implementations of
Smalltalk, and in the old Macintosh OS.

I think the JVM does (or did) something similar using an intermediate
object table.

– fxn

On 10/3/07, Rick DeNatale [email protected] wrote:

One of the things which the early Smalltalk memory management design
did was to enable the become method. In Smalltalk one could say:

object1 become: object2

Squeak still does support this.
When used with care it can be a wonderful tool, especially in
metaprogramming.
Cheers
Robert

On 10/3/07, Xavier N. [email protected] wrote:

Two uses of object handles were in the earliest implementations of
Smalltalk, and in the old Macintosh OS.

I think the JVM does (or did) something similar using an intermediate
object table.

Perhaps, but I don’t think that its a widely used implementation
strategy these days. The main advantage seems to be that it’s a
little easier to understand than more modern GC architectures. On the
other hand it tends to limit the total number of objects because of
the need for an object handle table.

One of the things which the early Smalltalk memory management design
did was to enable the become method. In Smalltalk one could say:

object1 become: object2

and the objects referenced by object1 and object2 would swap
identities, kind of a ‘Freaky Friday’ effect
http://www.imdb.com/title/tt0322330/ This was used mostly to allow
collection objects to be resized.

To get around the limitations of a fixed size object table, it became
standard practice to let the handles exist in the heap along with the
objects, or perhaps in a separate heap. The handle contained a
pointer to the bulk of the object and a few bit fields used for GC and
other housekeeping.

These days it’s much more common to find object references to be
direct pointers with bit tagging to identify special immediate
references, and the non-pointer contents of the handle moved into
header fields in non-immediate objects. The need for become: in
Smalltalk was obviated by refactoring the collection classes to hold
their contents in a separate array so that resizing could be done by
copying the contents array to a larger array rather than copying self
to a larger version and doing self become:largerSelf at the same time
the semantics of become: changed from the two-way swapping to a
one-way version which scanned object memory for references to the old
object and changing them to point to the new.

Many modern GC designs move objects during GC, and some of these still
use indirect forwarding pointers to a limited extent, usually
temporarily during GC.


Rick DeNatale

My blog on Ruby
http://talklikeaduck.denhaven2.com/

On 10/2/07, Rick DeNatale [email protected] wrote:

I prefer the term Object Reference myself, and see Object Handle as a
particular implementation (at least as the term applies to the systems
I just described).

I see using a memory address as a particular implementation of a
“handle”. I was thinking that the term “pointer” may be good enough,
but most think of a pointer as a memory address.

The problem with the term “reference” is that in the context of
call-by-reference, it implies something closer to an alias (arguments
of the function refer to the lvalue that the function was passed). In
that context, if a variable is an object reference, “a = b” would be
equivalent to a.become(b), which is definitely not what ruby does.

In the context of the original discussion (call-by-*), call-by-handle
seems like a good description for ruby. Variables simply hold object
handles.

On 10/3/07, Robert D. [email protected] wrote:

On 10/3/07, Rick DeNatale [email protected] wrote:

One of the things which the early Smalltalk memory management design
did was to enable the become method. In Smalltalk one could say:

object1 become: object2

Squeak still does support this.
When used with care it can be a wonderful tool, especially in metaprogramming.

Yep, it looks like Squeak has both ProtoObject#become: which has the
old swap semantics, and Object#becomeForward: which is one-way.

A quick look at the senders of #become: in the standard 3.9 image
seems to indicate that none of them actually use the swap they are all
becoming a newly created and otherwise unreferenced object, which
won’t be referenced when the method returns.


Rick DeNatale

My blog on Ruby
http://talklikeaduck.denhaven2.com/

On 10/3/07, Eric M. [email protected] wrote:

call-by-reference, it implies something closer to an alias (arguments
of the function refer to the lvalue that the function was passed). In
that context, if a variable is an object reference, “a = b” would be
equivalent to a.become(b), which is definitely not what ruby does.

In the context of the original discussion (call-by-*), call-by-handle
seems like a good description for ruby. Variables simply hold object
handles.

Call by object reference has been used for many years.
http://www.google.com/search?hl=en&q="call+by+object+reference

Call by object handle has not:
http://www.google.com/search?q="call+by+object+handle


Rick DeNatale
Fine Object Oriented Programming since the 1980s

My blog on Ruby
http://talklikeaduck.denhaven2.com/

2007/10/2, Robert D. [email protected]:

some data. And call by object reference gives the called method read
passing semantics after all.
Completely agree. +1 for “call by object reference”. What a wonderful
resolution: two options were debunked and a third alternative is
chosen as the winner. :slight_smile:

A side remark to Robert’s witty remark about the “truth value and
number of supporters”. This was really funny and a good defense, but
on the serious side, I honor the opinions of most of the lists
‘regulars’, even if I do not show it well all the time - which is bad
style from my part :(. (Comment ça va Xavier? :wink:

:slight_smile: As always, it was fun debating with you, Robert.

Kind regards

robert

On 10/3/07, Rick DeNatale [email protected] wrote:

Call by object reference has been used for many years.
http://www.google.com/search?hl=en&q="call+by+object+reference

Call by object handle has not:
http://www.google.com/search?q="call+by+object+handle
—> http://effbot.org/zone/call-by-object.htm
Funny how this has been discussed before :wink:
Robert

On 04.10.2007 19:45, Paul B. wrote:

created; you can only change the object to which it refers.

the description at

Under strict interpretation of this definition I think Ruby is not
call-by-reference, since the address of a variable is never passed, but
rather the object to which the variable refers.

Not the object is passed but the address / handle or however you want to
name it. If it were the object we’d have call by value IMHO (objects
are values in Ruby).

Strictly speaking, Ruby
is call by value (of the variable), but since this isn’t very
descriptive of how Ruby actually works, call by object reference sounds
better to me.

Yep, I’ve settled with call by object reference. However, I still
believe that call by reference is closer than call by value because the
latter would imply that copies of objects are passed and so
modifications of objects cannot have side effects on the caller. This
is a dangerous assumption. :slight_smile:

I think the muddiness comes from the terms not being descriptive enough
in their naming; they don’t describe in their names what entity is being
passed by value or reference (be it object, variable, or otherwise).

Good point. Side note: I find it extremely interesting how much debate
we can have about terms in a subject as formalized as computer science.

The call by object reference suggestion addresses this issue perfectly.

Right.

Also note that the C2 wiki gives a third definition of
call-by-reference:

http://c2.com/cgi/wiki?CallByReference

Actually I believe this is not a third definition of call by reference
but the same we had before (wikipedia). I’d disregard the comment in
italics because IMHO that makes the mistake to use C++ reference
semantics here. IMHO the crucial bit about CBR is the aliasing effect,
i.e. modifications of the value are visible to the caller.

Kind regards

robert

After reading this interesting thread, I think we might have a chance
at coining a new term here. How about:

Call by copied reference? Or call by temporary reference? I don’t
see anything particularly “objecty” about this distinction, per se.
I think it is a truly different passing convention that has convenient
merits distinct from the coarse approximations mentioned earlier.
Best regards,

-r.

On Tue, Oct 02, 2007 at 12:29:37AM +0900, Robert K. wrote:

  1. C++ R. type is a special beast which has some additional properties
    compared to 1. This does not only allow to reference a value but in
    fact you can say that it references a reference[1]. Or you can say
    that a C++ reference is an alias for a variable. Hence it allows to
    manipulate a variable in a calling scope.

A reference to another reference is explicitly disallowed in C++;
attempt to do this usually result in a reference to the original object.
The implication of this is that you cannot change a reference once it is
created; you can only change the object to which it refers.

As you point out, variable alias is an apt description of a C++
reference.

References in Ruby are IMO very similar to references in C++, with the
exception of assignment semantics. Assignment on a reference in C++
calls the referred object’s assignment operator, while assignment on a
reference in Ruby reassigns the reference.

Ruby’s evaluation strategy is actually “call by reference” although
the description at
http://en.wikipedia.org/wiki/Call_by_reference#Call_by_reference does
not cover Ruby properly - unless you interpret “temporary object” as
“copy of a reference” because this is how it works.

This description sounds very C+±centric to me. In particular, I’ve
never heard Lvalue used as part of the definition of call-by-reference
(the discussion page seems to back me up on this a little). I think
foldoc’s definition is better:

http://foldoc.org/?call-by-reference

call-by-reference

An argument passing convention where the address of an
argument variable is passed to a function or procedure, as opposed to
passing the value of the argument expression. Execution of the
function or procedure may have side-effects on the actual argument as
seen by the caller. The C language’s “&” (address of) and “*”
(dereference) operators allow the programmer to code explicit
call-by-reference. Other languages provide special syntax to declare
reference arguments (e.g. ALGOL 60).

Under strict interpretation of this definition I think Ruby is not
call-by-reference, since the address of a variable is never passed, but
rather the object to which the variable refers. Strictly speaking, Ruby
is call by value (of the variable), but since this isn’t very
descriptive of how Ruby actually works, call by object reference sounds
better to me.

I think the muddiness comes from the terms not being descriptive enough
in their naming; they don’t describe in their names what entity is being
passed by value or reference (be it object, variable, or otherwise).
The call by object reference suggestion addresses this issue perfectly.

Also note that the C2 wiki gives a third definition of
call-by-reference:

http://c2.com/cgi/wiki?CallByReference

Paul

This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.

| Privacy Policy | Terms of Service | Remote Ruby Jobs