On 9/27/07, Fernando Perez wrote: > > On 9/27/07, Robert Bradshaw wrote: > > > You have a good point, though fortunately we're looking for refcounts > > so low that (essentially) nothing else can be holding onto it but the > > current stack frame. If b is pointing to a, it doesn't matter how > > many other things are (directly or indirectly). If nothing is > > pointing to it directly, it's difficult (but not impossible) for > > things to safely point to it indirectly. Also, we would only play > > this trick with SAGE elements, which we have more control over. > > The subtlety appears if the object you're dealing with is itself a > view of something else: > > In [3]: a = N.arange(10) > > In [4]: b = a[::2] > > In [5]: sys.getrefcount(b) > Out[5]: 2 > > In [6]: sys.getrefcount(a) > Out[6]: 3 >
I think there might be some confusion here over what is an "object" and what is a "reference" to an object. The first object here is the result of 'N.arange(10)'. sage: sys.getrefcount( N.arange(10) ) 1 because using 'N.arange(10)' in this function call constitutes just 1 reference to this object. But when 'a' is also created as a reference to that object sage: a = N.arange(10) sage: sys.getrefcount(a) 2 the object denoted by 'N.arange(10)' already has two many references to safely be manipulated in-place! Remember that what gets passed to 'sys.getrefcount(a)' is the value of 'a', not 'a' itself. If we were to change this object, then then the object referenced by 'a' would also change and that is exactly the kind of side-effect that we want to avoid. So in this case if we can only do in-place operations on objects whose reference count is 1, you might wonder just how useful this could be ... But consider this: sage: sys.getrefcount([1,2]) 1 The expression '[1,2]' creates a list object. It's only reference is in the function call. So now write: sage: [1,2].__add__([3,5]).__add__([7,8]) [1, 2, 3, 5, 7, 8] where __add__ is a list method. According to the proposed semantics the __add__ operation above can safely operate in-place, i.e. first '3,5' is inserted (distructively) into the object '[1,2]' and then '7,8' is inserted into the *same* object. But if I write: sage: a=[1,2] sage: sys.getrefcount(a) 2 sage: a.__add__([3,5]).__add__([7,8]) [1, 2, 3, 5, 7, 8] then it is no longer safe to simply insert '3,5' into the object denoted by '[1,2]' since that will affect the value of 'a'. So instead we first of all make a new copy of the list '[1,2]' and perform the insertion into it. Regards, Bill Page. --~--~---------~--~----~------------~-------~--~----~ To post to this group, send email to sage-devel@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/sage-devel URLs: http://sage.scipy.org/sage/ and http://modular.math.washington.edu/sage/ -~----------~----~----~----~------~----~------~--~---