anything like C++ references?

Adam Ruth owski at hotmail.com
Wed Jul 16 21:06:40 CEST 2003


In <mailman.1058377226.21359.python-list at python.org> Michael Chermside  
wrote:
> Adam Ruth writes:
>> I assume that you're referring to people 'faking' pointer in Python (
>> such as wrapping variables in lists, etc.)  I'd ammend your statement 
>> to  say:    And the worst thing you can do is to obscure the issue 
>> even more by  disguising them as something else, WHEN YOU DON'T 
>> REALLY HAVE TO.  In Python, there is no situation where "you really 
>> can't avoid pointers".   It's only when you program C or C++ in 
>> Python that you think you can't  avoid pointers.  There are much 
>> better idioms to achieve the desired  results.
> 
> Look, first of all, let me say that I disagree with Stephen Horne in
> this discussion. Or, to be more precise, I think that the approach he
> is using is not one which is useful in describing Python. HOWEVER,
> that doesn't mean that there's NOTHING to what he is saying, and your
> claim that there is no situation requiring "pointers" in Python seems
> wrong to me.
> 
> Actually (to be quite pedantic) it is technically true. For instance,
> I could write a program in Python which simulated a turing machine,
> and then write the entire program to be executed on THAT. But this
> is a meaningless definition for "requiring" a feature -- by this
> definition NO feature is ever needed if the language is turing 
> equivalent without it... for instance, Python doesn't ever need
> classes, modules, dictionarys, or functions (I'm pretty sure a
> turing machine could be written which didn't use any of these).
> 
> What's more useful is to say that a feature is not "needed" if there's
> a straightforward alternate way to handle the situations where it 
> would normally be used. For instance this (using C++ syntax for 
> "references"):
>
>     def returnsMultipleValues(x, &minusFive, &timesFive):
>         """Calculates x+5, x-5, and x*5."""
>         *minusFive = x - 5
>         *timesFive = x * 5
>         return x + 5
> 
> Is unnecessary, since this:
> 
>     def returnsMultipleValues(x):
>         return x + 5, x - 5, x * 5
> 
> would work fine. However, there are some places where it IS useful to
> be able to modify a value within a routine. I have written code like
> this:
> 
>      i = [0]
>      stuff.append( makeNewComplexObject(i, 'name', 'fred') )
>      stuff.append( makeNewComplexObject(i, 'age', 17) )
>      stuff.append( makeNewComplexObject(i, 'item') )
>      stuff.append( makeNewComplexObject(i, 'item') )
> 
> where the source for makeNewComplexObject() went like this:
> 
>      def makeNewComplexObject(iBox, objName, *objArgs):
>          # increment i
>          i = iBox[0]
>          iBox[0] += 1
> 
>          if objName == 'name':
>              # some simple cases
>              return new NameObject(*objArgs)
>          elif objName == 'age':
>              # some complex cases
>              yrsOld = objArgs[0]
>              if yrsOld >= 18:
>                  return new AdultAge(*objArgs)
>              else:
>                  return new MinorAge(*objArgs)
>          elif objName == 'item':
>              # some cases that use i
>              return new IndexedItem(i)
> 
> Now, clearly, this code was inspired by C code which used an
> idiom like this:
> 
>     i = 0
>     stuff[i] = newComplexObject(i++, "name", "fred")
>     stuff[i] = newComplexObject(i++, "age", 17)
>     stuff[i] = newComplexObject(i++, "item")
>     stuff[i] = newComplexObject(i++, "item")
> 
> And certainly it *can* be rewritten in Python without "boxing" the
> variable i. However, it would also be nice to be ABLE to "box" the
> variable i. So it's not as if references would be USELESS in Python.
> I just think it'd be better handled differently (one-item list, or
> maybe a container class) rather than redefining assignment in Python
> as Stephen seems to prefer.[1]
> 
> -- Michael Chermside
> 
> [1] - Stephen doesn't want to change Python now for historical
>    reasons. But my position is that if I were inventing a NEW
>    language I'd do it Python's way by choice, because I think
>    it's better.
> 

You are correct in that there are times when pointer semantics would be 
somewhat useful, but they're never necessary.  His statement was that 
there are time that "you really can't avoid pointers".  That's not true.  
I definitely went a little overboard, and it sounds like I'm saying, 
"not only are pointers not necessary, they're never desirable".  My tone 
was a bit more knee jerk than was prudent.

Your code example isn't really about pointers, though, as the C++ 
version doesn't use pointers.  There's also another difference, the 
caller is responsible for incrementing the counter, which is quite 
different than your Python version.  There are a number of ways to write 
that without "pointers" that express the intent just as clearly, if not 
more.  The real question is what does the i represent?  If it represents 
the index of the object in the list, then this is more clear:


>      stuff.append( makeNewComplexObject(len(stuff), 'name', 'fred') )
>      stuff.append( makeNewComplexObject(len(stuff), 'age', 17) )
>      stuff.append( makeNewComplexObject(len(stuff), 'item') )
>      stuff.append( makeNewComplexObject(len(stuff), 'item') ) 

In the worst case (needing the most new code to implement) it would need 
to be written with a very small "counter" class:

>	   	class Counter(object):
>			def __init__(self, initial=0):
>				self.value = initial
>			def inc(self):
>				self.value += 1
>				return self.value

>      stuff.append( makeNewComplexObject(i.inc(), 'name', 'fred') )
>      stuff.append( makeNewComplexObject(i.inc(), 'age', 17) )
>      stuff.append( makeNewComplexObject(i.inc(), 'item') )
>      stuff.append( makeNewComplexObject(i.inc(), 'item') )   

This is just as clear as the C++ version, and more clear than the Python 
version that wraps with the list.

This example, though, doesn't really show the difference, it's too 
trivial.  All of the versions are clear enough, with the difference 
being academic. 

I would be interested in seeing a more complex example where something 
would be substantially cleaner with pointers.  I have to acknowledge the 
possibility that they exist, I don't know everything... yet :)

Adam Ruth




More information about the Python-list mailing list