Addressing the last element of a list

Bengt Richter bokr at oz.net
Mon Nov 14 13:32:33 EST 2005


On Mon, 14 Nov 2005 09:53:34 -0500, Mike Meyer <mwm at mired.org> wrote:

>Antoon Pardon <apardon at forel.vub.ac.be> writes:
>> Op 2005-11-10, Mike Meyer schreef <mwm at mired.org>:
>>> [Context recovered from top posting.]
>>> "bonono at gmail.com" <bonono at gmail.com> writes:
>>>> Daniel Crespo wrote:
>>>>> Well, I hope that newcomers to Python don't confuse himselves :)
>>>> This mutable/immutable object and name/variable is confusing.
>>> Only if you have to overcome a conviction that variables behave in a
>>> different way. If you've never seen them behave another way, or have
>>> already gotten used to this model from another language (it dates back
>>> to the 60s, if not the late 50s), then it's no problem. I'm sure the
>>> problem exists in the opposite direction, except that few people
>>> travel that route.
>>> Most OO languages do the name/variable thing, but some of the popular
>>> ones aren't consistent about it, giving some types "special" status,
>>> so that sometimes "a = b" causes b to be copied onto a, and sometimes
>>> it causes a to become a pointer to b. I find a consistent approach is
>>> preferable.
>> But what about a consistent approach, that allows choice.
>
>It's been done in other languages. But it requires more care than one
>would think.
>
>> Like having an assignment operator (let use @= for it) next to a
>> (re)bind operator.
>>
>> We could then have something like the following.
>>
>> a = 5
>> b = a
>> a @= 7
>> b ==> would result in 7.
>
>You've just overwritten the object referred to by the token "5" in the
>source code with the value 7, so you get:
>
>print 5
>7
>
>Not exactly a desirable outcome, but some language implementations
>have allowed this kind of thing in the past. You either have to make
>all objects mutable, or disallow assignment to immutable objects,
>which sort of defeats the purpose.
>
>Another approach is to have a special object type if you want to allow
>assignment to the object it refers to. That's what Python does now, it
>just doesn't have a syntax just to support that. If it did, your
>example might look like:
>
>a := 5
>b = @a
>a := 7
>@b ==> would result in 7
>
If you are willing to keep your "variables" in a namespace, it's easy
to make "pointers" that you can dereference like @b, except
-- given a preliminary:
(see PNS from http://groups.google.com/group/comp.lang.python/msg/54a7ab01906683ca )

 >>> from pns import PNS
 >>> class NS(object):
 ...     def __call__(self, name): return PNS(self, name)
 ...
 >>> ns = NS()

-- and then you have to spell it a little differently:

 >>> ns.a = 5    # a := 5
 >>> b = ns('a') # b = @a
 >>> ns.a = 7    # a := 7
 >>> b.v         # @b
 7


For another slant, laundering all ns assignments through pickle dumps/loads
to get a fresh value so as not to share references, and simulate value
assignment sematics (I think? ;-/)

    http://groups.google.com/group/comp.lang.python/msg/f29cf8e25b42d5cb

with a different spelling for pointer use (ns['a'] instead of ns('a') above,
and b[:] instead of b.v)

The class also gave you a way to spell the typical C address/pointer/deref ops.
It's based on a name space class that gives you a name space object (say ns)
for the "variables" that you can get "pointers" to like ptr = &var and which
you can pass around and use with dereferencing like *ptr for either assignment
or on the right hand side. Once you have a names space ns = NSHorne() you can
set variables in the ordinary way as attributes, or get "pointers" and use
them via *p semantics

 >>> from ns_horne import NSHorne
 >>> ns = NSHorne()
 >>> ns.x = 'x value'
 >>> ptr = ns['x']
 >>> ptr[:]
 'x value'

Now make a function that will use the pointer
 >>> def set(p, v):
 ...     p[:] = v
 ...
 >>> set(ptr, 123)

Check indirect result
 >>> ns.x
 123
 >>> ptr[:]
 123
 >>> ptr[:] += 321
 >>> ns.x
 444

Pseudo-value-semantics:
 >>> from ns_horne import NSHorne
 >>> ns = NSHorne()
 >>> ns.z = [1,2]
 >>> pz = ns['z']
 >>> pz[:]
 [1, 2]
 >>> ns.z2 = pz[:]
 >>> ns.z
 [1, 2]
 >>> ns.z2
 [1, 2]
 >>> pz[:][0]='z via pz'
 >>> ns.z
 ['z via pz', 2]
 >>> ns.z2
 [1, 2]
 >>> pz[:]
 ['z via pz', 2]

Or value semantics without confusing with pointer stuff:
 >>> ns.z3 = ns.z2

now equal values, but not the same objects:
 >>> ns.z3, ns.z2
 ([1, 2], [1, 2])
 >>> ns.z2[1]='z2 via ns.z2'
 >>> ns.z3
 [1, 2]
 >>> ns.z2
 [1, 'z2 via ns.z2']

Regards,
Bengt Richter



More information about the Python-list mailing list