Velocity Reviews

Velocity Reviews (http://www.velocityreviews.com/forums/index.php)
-   Python (http://www.velocityreviews.com/forums/f43-python.html)
-   -   RE: anything like C++ references? (http://www.velocityreviews.com/forums/t319635-re-anything-like-c-references.html)

Tim Peters 07-13-2003 08:57 PM

RE: anything like C++ references?
 
[Stephen Horne]
> ...
> The fact is that 'assignment' has a common meaning separate from the
> choice of programming language,


Well, that's not a fact, although there may be much commonality among the
(necessarily few, if you believe this) programming languages you've used.
Python's assignment semantics are in fact common among languages
higher-level than those of the Fortran/COBOL/Algol/C ilk. For examples,
Lisp, SNOBOL4, Scheme, Smalltalk and Icon are (very) much like Python in
this respect. So is Java in the end, although the underlying machinery is
more complicated there.

> and that the way Python handles name binding means that meaning is not
> respected by Python for mutable objects.


Python's assignment semantics don't vary according to object type.

> ...
> Python, however, does not respect this meaning.


This doesn't say more than that Python works differently than the languages
you've used. It really isn't a question of respect <wink>.

> It uses an arbitrary distinction based on whether or not the object
> has internals that can be usefully in-place modified, and uses that
> distinction to vary the effect of assignment in an arbitrary,
> inconsistent and error-prone way.


It's deliberate and thoroughly consistent. Any assignment semantics are
error-prone in some contexts, though (Python's included -- side effects are
like that). The simplicity and absolute consistency of Python-style
assignment semantics are probably easiest for first-time programmers to pick
up, and certainly dead easy for people coming from Lisp (etc) to pick up --
people coming from C (etc) often struggle with inappropriate expectations at
first.

> The need for a distinct tuple type is a symptom of the arbitrary
> nature of this.


Python's assignment semantics have nothing to do with mutability versus
immutability. The latter is a type-dependent distinction; assignment
semantics in Python don't depend on object type in any way.

> ...
> I've already posted too much on this, so this is going to be the end
> to it. But Pythons semantics with regard to mutable and immutable
> objects are simply bizarre.


Hmm. Mutable objects can be mutated, and immutable objects cannot be
mutated. That doesn't seem bizarre.

> A historic justification may be plausible and backward compatibility
> is then an important issue, but I really cannot accept claims that
> Python is doing the right thing here.


Well, I can assure you Guido wouldn't change anything about Python's
assignment semantics if were able to do it all over from scratch. That's a
puzzle for you to work out, then: is Guido unique, or are all Dutch people
that stupid <wink>?



Martin v. =?iso-8859-15?q?L=F6wis?= 07-13-2003 10:17 PM

Re: anything like C++ references?
 
Stephen Horne <intentionally@blank.co.uk> writes:

> 1. Why are dictionarys called dictionaries (rather than references to
> dictionarys or whatever)? Similar for lists and class instances.


Because they are the values themselves, instead of being references to
values. These values (like all other values) are objects, though,
which means they have identity, state, and behaviour.

You might be thinking of values which only have state and
behaviour. Such values are not supported in Python - objects always
have an identity.

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


Because all variables are references to objects. In Python, you cannot
have a variable that *is* a value - variables are always *bound* to
values, and accessing the variable yields the associated value. The
values exist independently from the variables they are bound to, and a
single value may be bound to different variables.

> 3. 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?


But there is: If I do

a = 1
b = a

then b *refers* the same value that a refers to. That is, the values
associated with a and b have the same identity.

> This excuse is, as I already said, invalid.


Which excuse? You have only listed questions in this message, not
excuses.

Regards,
Martin

Bryan 07-13-2003 10:42 PM

Re: anything like C++ references?
 

> 3. 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?
>


>>> a = (1, 2, 3)
>>> b = a
>>> id(a)

15471760
>>> id(b)

15471760
>>> print b[1]

2
>>>



i just referenced an immutable object via a "pointer" and i __did_not__
stuff it into a mutable object as you say.
a and b "point" to the same object.

bryan



Ian Bicking 07-14-2003 01:18 AM

Re: anything like C++ references?
 
I don't know why I'm participating, but it's feels hard to stay out of
this one...

On Sun, 2003-07-13 at 17:17, Martin v. L÷wis wrote
> > 3. 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?

>
> But there is: If I do
>
> a = 1
> b = a
>
> then b *refers* the same value that a refers to. That is, the values
> associated with a and b have the same identity.


I think, then, that Stephen maybe wants to do something like:

>>> a = ref(1)
>>> b = a
>>> b is a

True
>>> a + 2

3
>>> a = 5
>>> b

5

And so on. This is all quite doable in Python (implementation of ref
left to the reader), except for the "a = 5" part. Instead you'd have to
do something like "a.set(5)". Even though it is doable, of course, it's
by way of clever hacks.

The problem that Stephen is not appreciating is that this sort of
reference implies that "a" is a typed variable -- of type "pointer",
somehow implicitly declared when it was initially assigned a ref
object. (He's not alone, because just a little while ago someone
proposed a way to overload the meaning of "=", to achieve largely the
same functionality)

It might not be quite as ugly-seeming if we explicitly declared "a" as a
pointer. Besides the disinclination of people to add variable
declarations (though "global" already is one), it's more difficult
because there's now a new type that has to be usable everywhere, the
pointer type. All Python's code that expected, say, integers would have
to also be ready to dereference the argument and then use it. It could
probably be made seamless at the Python level fairly easily, but the C
would be annoying, no doubt.

One might think you could just use the references that already exists
(since variables are references, and everything is passed by
reference). But that's messed up, because that'd mean:

>>> b = 2
>>> pointer a
>>> a = 2
>>> a is b

True
>>> a = 5
>>> b

5

The ability to redefine the integers is obviously not a good feature
(though I remember someone saying you can accidentally do some stuff
like this in C extensions).

Anyway, that's my attempt at empathy with Stephen, if not agreement. If
he is wanting something other than what I've described, he should give
other examples, because code examples are better than words.

Ian




Stephen Horne 07-14-2003 02:24 AM

Qualified appology (was Re: anything like C++ references?)
 

Appols for changing the subject while still staying in the same topic
- I just wanted to highlight this over my earlier boneheaded posts.

This is a post of heavily qualified appologies. In summary, I've been
thick-headed but I still believe that Python is doing the wrong thing.

I hope I've actually achieved a degree of sanity on this attempt ;-)


On 14 Jul 2003 00:17:19 +0200, martin@v.loewis.de (Martin v. L÷wis)
wrote:

>Stephen Horne <intentionally@blank.co.uk> writes:
>
>> 1. Why are dictionarys called dictionaries (rather than references to
>> dictionarys or whatever)? Similar for lists and class instances.

>
>Because they are the values themselves, instead of being references to
>values. These values (like all other values) are objects, though,
>which means they have identity, state, and behaviour.


I've said my piece on meanings derived from computer science (and in
turn from mathematics, as it happens - variables as placeholders for
values predate electronic computers by quite some time.

People have tried to point out that copy-on-write is redundant for
immutable objects, but I've been too thick-headed. Sorry for that.

Even so, you can think of immutable objects as achieving 'expected'
assignment semantics simply because they are immutable. That does not
apply to mutable objects. So you can claim that Python behaviour is
consistent within itself, but only by claiming that it is consistently
different from this 'expected' behaviour.

Some people have already said that the word 'expected' is a fallacy -
that computer science doesn't have fixed definitions for these things.
Some have already named various languages which deviate in similar
ways in either some or all cases. But these languages are actually
deviating, either by convention or (in older cases) due to the
limitations of past machines. That's not the same thing as saying they
are doing 'the right thing' or that the computer science definitions
don't exist - all it means is that a lot of programmers who are
experienced in certain languages are familiar with this error-prone
system and used to compensating for its problems. But a modern
high-level language should do 'the right thing' - it should not be the
programmers job to make allowances for an outdated workaround designed
to give maximum performance by default on old machines irrespective of
reliability.

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

>
>Because all variables are references to objects.


All variables are implemented as references, but that is not the same
as saying that all values are references. As Guidos own words reveal
(I already posted the link twice) the purpose of using immutables
tuples is performance optimisation to save copying while still
defending against against accidental mutation (ie it provides the
computer theory standard assignment semantics efficiently).

The same rationale should equally apply to all types, including the
mutable types.

In particular, it should apply to class instances. I shouldn't need to
create separate mutable and immutable variants of classes to get this
as the mutability of content should be the decision of the container
rather than the content. I shouldn't need to force copying of class
instances in the container for the exact same reason that Guido
highlights for tuples.

Guidos own example is actually quite bug prone in its own way. It
behaves differently depending on whether you pass in the point values
as tuples or lists. That is potentially a subtle, intermittent,
hard-to-trace error waiting to happen. You can say 'validation' all
you want. I did that back in the PEP238 days, and didn't get much
support. What's good for the goose is good for the gander.

>> This excuse is, as I already said, invalid.

>
>Which excuse? You have only listed questions in this message, not
>excuses.


Looking back, I was unfair to Tim Peters. The 'excuse' was percieved
(mainly because I'm frustrated trying to get my point across, and
because a circularity that arose (unless I was thick-headed about that
too) in another post. I said 'if a then b', someone said 'no - a is
wrong because c', I said 'ah, but if c then d' and the reply to that
was 'no - c is wrong because a' - or at least I think that's what
happened. Possibly I just need some sleep.

I thought Tim was also guilty of this, but looking back I was wrong.
Sorry, Tim.

However, revisiting his post I still disagree with it...

"""
It's deliberate and thoroughly consistent. Any assignment semantics
are
error-prone in some contexts, though (Python's included -- side
effects are
like that). The simplicity and absolute consistency of Python-style
assignment semantics are probably easiest for first-time programmers
to pick
up, and certainly dead easy for people coming from Lisp (etc) to pick
up --
people coming from C (etc) often struggle with inappropriate
expectations at
first.
"""

At first glance it looked like Tim was saying 'its all assignment
semantics rather than type semantics', hence my misjudging him. But
one way or the other, there is an inconsistency between the behaviour
of mutable objects and the computer science definitions of 'variable',
'value' and 'assignment' which does not arise for immutable objects
(note careful wording - see earlier apology). Having copy-on-write for
all objects (obviously the actual copying never happening for
immutables) would be both fully self-consistent and consistent with
the computer science definitions. The lack of this definitely does
cause both confusion and errors.

I also disagree with Tims statement that "Any assignment semantics are
error-prone in some contexts". OK, mistakes can be made with any
syntax for anything, but in the context of this discussion it is
perfectly possible to get the best of both worlds.

Make pointers/references explicit and make all assignments
'copy-on-write', and as I said earlier you get both mutability
protection by default for all types and the ability to reference any
type indirectly. Avoid the problems that make pointers in C, C++,
Pascal etc so unreliable and, while perceptions of pointers as being
inherently bug prone may persist they would be irrational - having
pointers explicitly for all types would at worst be as bug prone as
the existing situation where implicit references exist, and in
particular where mutable types get abused to fake pointer/reference
capabilities. It needs extra notation, but when mutables are used to
fake pointers there is extra notation anyway - misleading notation.

I'm not an anti-side-effect fanatic. I just don't want them to happen
by default, and I don't have to worry about this every time I use a
mutable type. And there really is no need for that to happen.


Stephen Horne 07-14-2003 03:43 AM

Re: anything like C++ references?
 
On 13 Jul 2003 20:18:25 -0500, Ian Bicking <ianb@colorstudy.com>
wrote:

>I think, then, that Stephen maybe wants to do something like:
>
>>>> a = ref(1)
>>>> b = a
>>>> b is a

>True
>>>> a + 2

>3
>>>> a = 5
>>>> b

>5
>
>And so on. This is all quite doable in Python (implementation of ref
>left to the reader), except for the "a = 5" part. Instead you'd have to
>do something like "a.set(5)". Even though it is doable, of course, it's
>by way of clever hacks.


Well, during the 'debate', that's the basic idea that involved -
except that I'd use explicit pointer-dereferencing syntax.

Imagine, for instance, changing all assignments and other 'copying' to
use a copy-on-write system. Then add a pointer type and a 'newcopyof'
operator. And nick the C-style prefix '*' for dereferencing and add
'&' as a 'make a pointer to this object' operator (absolutely NOT a
physical memory address).

>>> a = 5
>>> b = a
>>> b is a

False

>>> a = &5
>>> b = a
>>> *b is *a

True

>>> a = &5
>>> b = newcopyof a # could be "b = &(*a)" in principle
>>> *b is *a

False

>>> a = BadPtr
>>> b = *a

Traceback (most recent call last):
File "<stdin>", line 11, in ?
BadDeref: pointer does not reference a valid object

>>> a = *1

Traceback (most recent call last):
File "<stdin>", line 12, in ?
TypeError: object doesn't support dereference operator


No need for a 'delete' equivalent because of garbage collection. No
possibility of referencing a bad pointer as there is no way to create
a bad pointer - except, of course, for the explicit BadPtr (or
whatever) which throws an exception if dereferenced.

>The problem that Stephen is not appreciating is that this sort of
>reference implies that "a" is a typed variable -- of type "pointer",
>somehow implicitly declared when it was initially assigned a ref
>object. (He's not alone, because just a little while ago someone
>proposed a way to overload the meaning of "=", to achieve largely the
>same functionality)


No - I'm aware of the issue. When people use lists to fake pointers,
they already need explicit notation to tell Python what they are
doing. I'd just rather go back to having explicit pointers, though
implemented in a way which is appropriate to scripting languages and
which eliminates the major reliability issues of C-like pointer
mechanisms.

Using this approach, I don't need to declare variable types but I do
need to be explicit about when I'm using pointed-to-values and when
I'm using the pointers themselves.

Self-dereferencing pointers might also be nice in some ways, but with
serious problems. In C++, binding to the referenced object is done in
the declaration. That can't happen in Python, so a different method
would be needed - a special assignment operator, probably.

That then leads to the fundamental flaw. This couldn't be used to do
what, in C++, it does best - mimicking what Pascal calls 'var'
parameters.

If there were a 'procedure' abstraction, distinct from 'function', I
might be happy for all parameters to be implicitly dereferenced
pointers - I'd be happy being unable to change the pointer in this
case (in fact I'd like it enforced) - to get var parameter like
behaviour. There are nasty subtleties, though (what if someone creates
a pointer to the parameter, for instance - can it be used to change
the supposedly fixed pointer?). The C-like approach of just passing a
pointer as the expected parameter type has the advantage of simplicity
if nothing else.

>Anyway, that's my attempt at empathy with Stephen, if not agreement. If
>he is wanting something other than what I've described, he should give
>other examples, because code examples are better than words.


I hope I've explained, now. It wasn't in my mind when I started out,
but it would certainly be a way to solve what I see as serious
problems.

A realistic change for Python? - I doubt it. It could be technically
feasable, perhaps (a 'from future' thing adding copy-on-write and the
new operators etc) but interaction with past modules would create
problems. And with my very limited understanding of Python internals,
I'm sure I'm missing much bigger problems. Not to mention that at this
point, the change would probably be so fundamental as to actually
create a new language.

This does, however, give an alternative that *could* have been
plausible (in a parallel universe, perhaps), and which would not have
resulted in certain common problems that do occur now.


Stephen Horne 07-14-2003 03:51 AM

Re: anything like C++ references?
 
On Sun, 13 Jul 2003 22:42:21 GMT, "Bryan" <belred1@yahoo.com> wrote:

>
>> 3. 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?
>>

>
>>>> a = (1, 2, 3)
>>>> b = a
>>>> id(a)

>15471760
>>>> id(b)

>15471760
>>>> print b[1]

>2
>>>>

>
>
>i just referenced an immutable object via a "pointer" and i __did_not__
>stuff it into a mutable object as you say.
>a and b "point" to the same object.


Technically, but what is the point? You can't do pointer-style things
with it. You can't change the object in any way without changing the
id, and you can't use the mechanism to, for instance, allow 'var'
parameters.

In short, you are showing evidence of the use of pointers internally
within Python, but that is not the same as providing pointer-like
semantics.


Martin v. =?iso-8859-15?q?L=F6wis?= 07-14-2003 05:25 AM

Re: anything like C++ references?
 
Stephen Horne <intentionally@blank.co.uk> writes:

> >>>> a = ref(1)
> >>>> b = a

[...]
> >>>> a = 5
> >>>> b

> >5

[...]
> Well, during the 'debate', that's the basic idea that involved -
> except that I'd use explicit pointer-dereferencing syntax.


This is a very bad idea. You want to create a reference to the object
1? Then I assume that assigning to "a" would *change* the value of 1?
But 1 is an immutable object, it cannot change!

> Imagine, for instance, changing all assignments and other 'copying' to
> use a copy-on-write system.


That assumes that there is the notion of copying values in the first
place. Objects, in general, don't support copying - and assignment has
nothing to do with copying.

> >>> a = &5
> >>> b = newcopyof a # could be "b = &(*a)" in principle
> >>> *b is *a

> False


Again, objects don't support copying. For immutable objects (like
numbers), copying is also a pointless operation: If there where a
standard .copy method on objects, numbers would return themselves.

There is no way, in the language, to express that you want different
copies of the value 5. This is completely different from the notion of
values in C or C++, where each occurrence of the literal 5 creates a
new value whose state is 5.

Regards,
Martin

Bryan 07-14-2003 06:28 AM

Re: anything like C++ references?
 

"Stephen Horne" <intentionally@blank.co.uk> wrote in message
news:rp94hvc8fg6h91oe7ctqq9jn9ku3nlud1k@4ax.com...
> On Sun, 13 Jul 2003 22:42:21 GMT, "Bryan" <belred1@yahoo.com> wrote:
>
> >
> >> 3. 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?
> >>

> >
> >>>> a = (1, 2, 3)
> >>>> b = a
> >>>> id(a)

> >15471760
> >>>> id(b)

> >15471760
> >>>> print b[1]

> >2
> >>>>

> >
> >
> >i just referenced an immutable object via a "pointer" and i __did_not__
> >stuff it into a mutable object as you say.
> >a and b "point" to the same object.

>
> Technically, but what is the point? You can't do pointer-style things
> with it. You can't change the object in any way without changing the
> id, and you can't use the mechanism to, for instance, allow 'var'
> parameters.
>


can you show what functionality is missing by not being able to do
"pointer-style things"? here are two variables:

a = (1, 2, 3)
b = [1, 2, 3]

one immutable, one mutable. please show an example of what "pointer-style
things" you would like to do.

i've read this entire thread so far, and from a practical point of view
(because that's all i really care about and what pays the bills), i really
don't understand what the problem is. personally, i don't care about the
strict definitions of computer science terms and what "variable" or
"pointer" means. i do care about how fast problems can be solved, how much
resources must be involved in solving that problem, and how much money can
be made/saved. for me, python is a winner in all this area. not having
pointers like c/c++ is such a blessing. i can't believe anyone would even
suggest that pointers and/or doing things with pointers be brought into
python. ok... one more time... let's bring this conversation down to
something practical. please show an example of pointer-style functionality
in any language that is missing/awkward/complicated in python. i'm not an
expert in python, i'm just very curious to understand what the true
practical issue is.

thanks,

bryan

> In short, you are showing evidence of the use of pointers internally
> within Python, but that is not the same as providing pointer-like
> semantics.
>




Erik Max Francis 07-14-2003 07:10 AM

Re: Qualified appology (was Re: anything like C++ references?)
 
Stephen Horne wrote:

> All variables are implemented as references, but that is not the same
> as saying that all values are references.


Right. And this is an extremely important point in Python. Variables
are bindings of names to objects. Objects are entities in and of
themselves. The object is what is mutable or immutable, not the name.
Names are transitory.

--
Erik Max Francis && max@alcyone.com && http://www.alcyone.com/max/
__ San Jose, CA, USA && 37 20 N 121 53 W && &tSftDotIotE
/ \ The little I know, I owe to my ignorance.
\__/ Sacha Guitry


All times are GMT. The time now is 05:46 PM.

Powered by vBulletin®. Copyright ©2000 - 2014, vBulletin Solutions, Inc.
SEO by vBSEO ©2010, Crawlability, Inc.