Automatic debugging of copy by reference errors?

Beliavsky beliavsky at aol.com
Mon Dec 11 09:21:05 EST 2006


Carl Banks wrote:
> Niels L Ellegaard wrote:
> > Marc 'BlackJack' Rintsch wrote:
> > > In <1165666093.996141.244760 at n67g2000cwd.googlegroups.com>, Niels L
> > > Ellegaard wrote:
> > > > I have been using scipy for some time now, but in the beginning I made
> > > > a few mistakes with copying by reference.
> > > But "copying by reference" is the way Python works.  Python never copies
> > > objects unless you explicitly ask for it.  So what you want is a warning
> > > for *every* assignment.
> >
> > Maybe I am on the wrong track here, but just to clarify myself:
> >
> > I wanted  a each object to know whether or not it was being referred to
> > by a living object, and I wanted to warn the user whenever he tried to
> > change an object that was being refered to by a living object.
>
> This really wouldn't work, trust us.  Objects do not know who
> references them, and are not notified when bound to a symbol or added
> to a container.  However, I do think you're right about one thing: it
> would be nice to have a tool that can catch errors of this sort, even
> if it's imperfect (as it must be).
>
> ISTM the big catch for Fortran programmers is when a mutable container
> is referenced from multiple places; thus a change via one reference
> will confusingly show up via the other one.

As a Fortranner, I agree. Is there an explanation online of why Python
treats lists the way it does? I did not see this question in the Python
FAQs at http://www.python.org/doc/faq/ .

Here is a short Python code and a Fortran 95 equivalent.

a    = [1]
c    = a[:]
b    = a
b[0] = 10
print a,b,c

output: [10] [10] [1]

program xalias
implicit none
integer, target  :: a(1)
integer            :: c(1)
integer, pointer :: b(:)
a =  [1]
c =   a
b =>  a
b(1) = 10
print*,a,b,c
end program xalias

output: 10 10 1

It is possible to get similar behavior when assigning an array (list)
in Fortran as in Python, but one must explicitly use a pointer and "=>"
instead of "=". This works well IMO, causing fewer surprises, and I
have never heard Fortranners complain about it.

Another way of writing the Fortran code so that "a" and "b" occupy the
same memory is to use EQUIVALENCE.

program xequivalence
implicit none
integer :: a(1),b(1)
integer :: c(1)
equivalence (a,b)
a    =  [1]
c    =   a
b    =   a
b(1) = 10
print*,a,b,c
end program xequivalence

output: 10 10 1

EQUIVALENCE is considered a "harmful" feature of early FORTRAN
http://www.ibiblio.org/pub/languages/fortran/ch1-5.html .




More information about the Python-list mailing list