[Edu-sig] Python sequences by reference - how to make clear?

Marc Keller mkeller@noos.fr
Thu, 19 Sep 2002 10:49:38 +0200


I taught Algorithmics to mathematicians, and I had, of course, the same
problems.
But it seems to me that mathematicians have to be conscious of this
difference between
object and value of this object, which in is more precise than the
dichotomy variable and value of this variable, but not contradictory.
On another side it seems to me easier to explain to mathematician the
notion of mutable-immutable objects than to explain pointers...
In your example, if I change the position of the statement "rec = [0]*n"
as in 
def do_process1(LL):
    n=len(LL[0])
    Res=[]
    for row in LL:
        rec = [0]*n
        rec[0] = row[0]
        # further code - modifying rec 
        # lots of conditional processing and such...
        # ...
        Res += [rec]
    return Res
the result of: do_process1(L_L)
is evidently [[1, 0, 0], [2, 0, 0], [3, 0, 0]]
And even for mathematicians, it is evident that functions do_process and
do_process1
are not automatically equivalent.

Marc Keller
#§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§
Michal Kaukic wrote:
> 
> Hi,
> 
>    we like Python - I use it (with Numeric and SciPy modules)
> for teaching of Numerical analysis and my colleague is doing
> some research in discrete optimization in Python. And he often
> surprises me with non-conformal use of language :-)
> 
>    We are mathematicians, not programmers. I suppose, he believes
> that Python "thinks" like Mathematician. Yesterday, he was struggling
> with the code shown below (somewhat simplified):
> 
> 
> L_L=[[1,2,3], [2,3,4], [3,4,5]]
> 
> def do_process(LL):
>     n=len(LL[0])
>     rec = [0]*n
>     Res=[]
> 
>     for row in LL:
>         rec[0] = row[0]
>         # further code - modifying rec
>         # lots of conditional processing and such...
>         # ...
>         Res += [rec]
> 
>     return Res
> 
> ---------------------------------------------
> 
> After calling do_process(L_L), the "expected" result should be
> 
>    [[1, 0, 0], [2, 0, 0], [3, 0, 0]]
> 
> but the true result is
> 
>    [[3, 0, 0], [3, 0, 0], [3, 0, 0]].
> 
>    Yes, this is fully in accordance with how the Python language should behave:
>        Res += [rec] inserts references to list object rec,
>        which are further modified... (he should use copy(rec) instead).
> 
>    But there is nothing to make this behaviour clearly VISIBLE in code.
> If I work with pointers in C/C++ I know and see they are pointers.
> You can say - we also know that rec is list object and so be careful with it.
> Yes, but consider the complex code where the similar constructs
> are very easy to overlook. And debugging of such code can be frustrating.
> 
>    My colleague was in state of despair and made thoughtful remarks
> about FORTRAN and Python similarity. He believes that Python is corrupting
> his (computer) memory...
> 
>    So what is the point? I wrote this message in hope that there are more people
> with similar experience. My question is - how to explain to novice non-programmer users
> (maybe mathematically "infected") the quirks of Python sequence objects? Which methodology to use
> in programs so we can clearly see we work with "pointers"?
> Or maybe someone can propose the changes to the Language to overcome this (psychological) barrier?
> I feel this as a serious obstacle in using Python (my students experienced it too).
> 
> Thanks,
>                   Mike
> 
> _______________________________________________
> Edu-sig mailing list
> Edu-sig@python.org
> http://mail.python.org/mailman/listinfo/edu-sig