anything like C++ references?

Adam Ruth owski at hotmail.com
Mon Jul 14 00:03:59 EDT 2003


Stephen Horne <intentionally at blank.co.uk> wrote in message news:<sag3hv4vf884ed7ouu5cv8ofnopp9j1t12 at 4ax.com>...
> On 13 Jul 2003 14:48:09 -0500, Ian Bicking <ianb at colorstudy.com>
> wrote:
> 
> >On Sun, 2003-07-13 at 12:51, Stephen Horne wrote:

> 1.  Why are the values of mutable objects always forced to be accessed
> via a pointer (or reference or whatever)?

Because *all* objects are accessed via pointer, sorta.

> Note that I am referring to a computer science, semantic
> pointer/reference/whatever - not to any pointers or references that
> may be used in the implementation of the binding of variables to
> values. The use, behind the scenes, of lazy copying as an optimisation
> is irrelevant to the computer science principles.
> 
> 2.  Why is there no way to reference an immutable object via a
> pointer, other than stuffing it into a mutable object designed for
> some purpose other than simple pointer behaviour?

They *are* referenced by pointer, sorta.  It's just that what is being
pointed to cannot be changed.  If you were using C and you had a
pointer to a variable in a region of memory that you couldn't change,
then you'd have, semantically, the equivalent.

In that case, how you do modify the value?  You don't, you only modify
the *pointer*.  If you want to change the pointer, you need to pass a
pointer to a pointer.  This is what doesn't exist in Python, and I
think it's what you're having problems with.  The same "problem"
exists in Java, but for slightly different reasons.

The Python method is completely consistent and all objects are treated
the same.  There are no *pointers* even though binding sometimes
behaves like they.  Binding doesn't always work like pointers, but it
always works like binding.

> 
> The truth is that this system is arbitrary, and that therefore this
> excuse is invalid.

The definition of what is and isn't immutable isn't arbitrary in the
sense of "Determined by chance, whim, or impulse, and not by
necessity, reason, or principle".  I'd say that the choices were made
on necessity, reason, and principle.  Just not the necessity, reason,
or principle you would have chosen.

What happens in this case?

char *myval = "my little pony";
myval[1] = 'e';

It would appear that C and C++ also have immutable types.  And in this
case the reason it's immutable bears no relation to the object or
type, but to it's location in memory, I'd say that that appears more
arbitrary.  "Some strings are immutable and some aren't" is worse than
"all strings are immutable".
 
> >The problem you have is you are still thinking of variables as slots,
> >which is not correct.  Variables in Python are bindings.  Assignment
> >never copies anything, or creates anything except for changing the
> >variable to point to a different address location.  *Every* Python
> >assignment (a=b) is like the C assignment (a=&b).  
> 
> The problem is that you are confusing implementation with semantics.
> The meanings of 'variable', 'value', 'assignment' etc are defined by
> computer science. Whether you arbitrarily change the meaning of
> 'assignment' or whether you arbitrarily change the meaning of
> 'variable', it amounts to the same thing.

I don't see the arbitrary change.  Python has one type of variable: A
pointer that cannot itself be dereferenced.  It's much more consistent
then having 3 types of variables (in C++).

> 
> >
> >> Tell me one case where it is sensible for a function to behave such
> >> that whether the caller sees a change in a variable it passed as its
> >> argument should depend on the type.

A function may see a change in a *value* not a variable.  That should
always depend on type and should depend on nothing else, a function
should always know what types it's working on.  In my C example above,
it would depend on nothing that could be discernable in the function.

If someone wrote a mutable integer class, then it would be a distinct
type from an immutable integer, and the function could work with 3
types:  immutable int, mutable int, and int.  If the function doesn't
know what it's working with, then the function writer should probably
look for another career.

> You miss my point. Your argument would equally apply to the need for
> an integer-specific division operator, for instance. Its all about how
> one function reacts in response to varying input. If you pass a
> mutable value to a function which expects an immutable one, you get an
> error. If you pass an immutable value to a function which expects a
> mutable one, you get an error. There is no good reason for a function
> to react to the distinction as evidenced by your own observation that
> what actually happens (and what should happen) is that you have two
> distinct variants of the function.

Not true.  If you pass a mutable to a function that expects an
immutable, you'll get no error.  There's nothing that can be done to
an immutable that can't be done to a mutable.  The opposite would give
an error, and should.  You wouln't call a function in C++ with an
object that has no object::doSomething() function if the function
expected it.  Whether an object is immutable or not, is no different
than knowing what methods it supports.  You wouldn't program against
an object without knowing its methods, likewise you need to know if
it's immutable.

This dicussion brings to light the fact that immutable/mutable isn't
really special in any way.  It just means that the object has no
methods to support mutability.  Just like the classic Dog class
inheriting from Animal.  Animal has no doBark() method, but Dog does. 
A function user shouldn't be surprised that a method that expects a
Dog would choke on an Animal.

> >> Tell me one case where an object storing values should care about
> >> callers mutating values it holds *only* for certain types.
> >
> >Objects don't *store* values, they *refer* to values.  You are still
> >thinking like you're in C (or C++).  This is why you are having a
> >problem.
> 
> No it is not. I'm thinking in terms of computer science, in which
> terms like 'variable', 'value' and 'assignment' are abstract concepts
> independent of the way in which they are implemented in a programming
> language.

The distinction is more to do with Dynamically version Static
languages.  You're quoting the definitions for Static languages like
they apply universally to all computer science.  They don't.  In C you
can have a variable that's an int, float, pointer, struct, etc.  In
Python you only get name (which can be read binding, or "limited"
pointer).  It's when you start forcing the semantics of value types
onto variables that you get confused.  Variable, value, and
assignement do mean different things in dynamic vs. static languages,
and that's because they're sematically different.  While they both use
the = operator to perform similar functions, they're different, and if
you expect them to be identical, you're going to be frustrated.

> One way or the other, Python is currently choosing not to respect the
> computer science definition of those terms. It may have historic and
> backward-compatability reasons, but that does not change the facts.
> This deviation from computer science definitions, whatever the excuse,
> is arbitrary, confusing and error prone. That is my problem.

It's not respecting the static language definitions of those terms,
but it shouldn't even try.  There are different meanings for those
words in mathematics, but you wouldn't try to express those
definitions in terms of C, it would be equally frustrating.  The
static definitions are merely abstractions of the mathematic meanings,
and the dynamic meanings are also abstract, but in a different
direction.

Adam Ruth




More information about the Python-list mailing list