[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

Reference vs. Reference

Robert Klemme

10/1/2007 3:30:00 PM

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. :-) 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#Comput...

Ruby's evaluation strategy is actually "call by reference" although
the description at
http://en.wikipedia.org/wiki/Call_by_reference#Call_by... 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

33 Answers

Robert Dober

10/1/2007 8:07:00 PM

0

On 10/1/07, Robert Klemme <shortcutter@googlemail.com> wrote:
> 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. :-) 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#Comput...
>
> 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... 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 ;)

--
what do I think about Ruby?
http://ruby-smalltalk.blo...

Robert Klemme

10/1/2007 10:05:00 PM

0

On 01.10.2007 22:07, Robert Dober wrote:
> On 10/1/07, Robert Klemme <shortcutter@googlemail.com> wrote:
>> 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. :-) 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#Comput...
>>
>> Ruby's evaluation strategy is actually "call by reference"
> Sorry Robert but I challange that statement,

It's a free country... :-)

> "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? :-)

> 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... 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 ;)

Raised to the power of three. :-)

robert

Eric Mahurin

10/2/2007 7:37:00 PM

0

On 10/1/07, Robert Klemme <shortcutter@googlemail.com> wrote:
> On 01.10.2007 22:07, Robert Dober wrote:
> >> although
> >> the description at
> >> http://en.wikipedia.org/wiki/Call_by_reference#Call_by... 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.

I agree with Robert Dober. 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

Rick DeNatale

10/2/2007 7:39:00 PM

0

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.denh...

Robert Dober

10/2/2007 8:54:00 PM

0

On 10/2/07, Rick DeNatale <rick.denatale@gmail.com> wrote:
> 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.
>
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? ;)

Cheers
Robert
--
what do I think about Ruby?
http://ruby-smalltalk.blo...

Peter C. Verhage

10/2/2007 10:18:00 PM

0

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

10/3/2007 3:24:00 AM

0

On 10/2/07, Peter C. Verhage <peter@no-nonsense.org> 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.denh...

Joel VanderWerf

10/3/2007 3:56:00 AM

0

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.

--
vjoel : Joel VanderWerf : path berkeley edu : 510 665 3407

Xavier Noria

10/3/2007 7:55:00 AM

0

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


Rick DeNatale

10/3/2007 12:59:00 PM

0

On 10/3/07, Xavier Noria <fxn@hashref.com> wrote:
> 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.

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/... 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.denh...