[Tutor] References and list aliasing in Perl and Python [Was: Re: Dictionaries]

Danny Yoo dyoo at hkn.eecs.berkeley.edu
Wed Jan 18 07:57:51 CET 2006


> > The terminology that the original poster uses ("references to another
> > object") sounds a lot like the original usage of symbolic "soft"
> > references in Perl.
> > (http://www.perl.com/doc/manual/html/pod/perlref.html)
> >
> > Perl programmers, for the most part, avoid them now because they're so
> > error prone. So if the original poster is thinking about symbolic
> > references, then we should encourage the poster to look into
> > dictionaries, since dictionaries are a fairly direct replacement for
> > that usage.
> >
> I did not know Perl programmers were moving away from references. That's
> new to me, and an interesting point.

[Note: I'll write some Perl code below.  Probably bad, nonidiomatic Perl
code.  I also have a high chance of saying something wrong.  If I do so,
someone please correct me.  *grin*

Also, whenever I say "Perl", I'll mean Perl 5 --- I understand that Perl 6
has a model that's similar to Python now.]


Hi Victor,

No, no, I'd better clarify this to try to avoid someone getting angry at
me.  Maybe I'll dig myself into a deeper hole, but oh well.

Perl has a distinction between "soft" symbolic references and "hard"
references.  I think symbolic references may have been a language mistake;
I think good Perl style these days has been to phase them out of usage.

Perl programmers seem to be perfectly happy with "hard" references:
(http://search.cpan.org/~nwclark/perl-5.8.7/pod/perlreftut.pod)


Python programmers like myself struggle a little when we talk about this
because, truthfully, we don't think about this much.  In Python, we pass
references around without with abandon: we might not even realize it!
Values in Python are all references.  For example:

### Python ###
>>> msg = list("hello world");
>>> greeting = msg
>>> id(msg)
466880
>>> id(greeting)
466880
##############

In Python, both 'msg' and 'greeting' are names that refer to the same list
value.  We see this because they have the same id().  And if we apply
mutation on the list value, we'll see this from both names:

### Python ###
>>> msg[1] = 'a'
>>> msg
['h', 'a', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'l', 'd']
>>> greeting
['h', 'a', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'l', 'd']
##############



Perl makes a distinction between values and references to those values, so
the following shows different results:

### Perl #########################
mumak:~ dyoo$ cat > test.pl
my @msg = split //, "hello world";
my @greeting = @msg;
print \@msg, "\n";
print \@greeting, "\n";
$msg[1] = 'a';
print "@msg\n";
print "@greeting\n";

mumak:~ dyoo$ perl -w test.pl
ARRAY(0x180b560)
ARRAY(0x180b5b4)
h a l l o   w o r l d
h e l l o   w o r l d
##################################

Here, we see that @msg and @greeting are really separate things in Perl:
the values are in different memory locations, and assignment copies the
data structures around.


To get the same aliasing effect as in Python, we'd have to explicitely ask
Perl to reference and dereference:

### Perl ###########################
my $msg = [split //, "hello world"];
my $greeting = $msg;
print $msg, "\n";
print $greeting, "\n";
$msg->[1] = 'a';
print "@$msg\n";
print "@$greeting\n";
#####################################

So Perl folks have a slightly more complex conceptual model: they make a
distinction bewteen values and references.  Python just has references.

There are tradeoffs here.  On the one hand, Python folks get caught off
guard when they first encounter list aliasing.  On the other, Perl folks
get caught off guard when they first try to make a hash whose values are
themselves lists.  *grin*


Hope this helps!



More information about the Tutor mailing list